﻿using BCCommon;
using BCCommon.PaymentEnums;
using BCCommon.TMS.Order;
using BCCommon.TMS.Transport;
using BCDto.Common.Payment.Payment;
using BCDto.Location;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.Driver;
using BCDto.TMS.Order;
using BCDto.TMS.Order.Order;
using BCDto.TMS.Order.OrderProcess;
using BCDto.Website.User;
using BCService.Common.Payment.Payment;
using System;

namespace BCService.TMS.Order.Order
{
    /// <summary>
    /// 订单处理
    /// </summary>
    public interface IOrderProcessService
    {
        /// <summary>
        /// 获取订单信息
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <returns></returns>
        OrderDto GetOrder(long orderId);
        /// <summary>
        /// 获取订单信息
        /// </summary>
        /// <param name="orderNo">订单编号</param>
        /// <returns></returns>
        OrderDto GetOrder(string orderNo);

        /// <summary>
        /// 获取订单信息
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="orderId">订单Id</param>
        /// <returns></returns>
        OrderDto GetWithUser(long userId, long orderId);

        /// <summary>
        /// 获取订单信息
        /// </summary>
        /// <param name="driverId">司机Id</param>
        /// <param name="orderId">订单Id</param>
        /// <returns></returns>
        OrderDto GetWithDriver(long driverId, long orderId);
        /// <summary>
        /// 获取订单信息列表
        /// </summary>
        /// <param name="adminDto">管理员信息</param>
        /// <param name="orderNo">订单编号</param>
        /// <param name="vehicleNo">车牌号</param>
        /// <param name="provinceCode">省编码</param>
        /// <param name="cityCode">城市编码</param>
        /// <param name="countyCode">区县编码</param>
        /// <param name="orderStatus">订单状态</param>
        /// <param name="goodsName">货物名称</param>
        /// <param name="userId">用户ID</param>
        /// <param name="driverId">司机ID</param>
        /// <param name="endProvinceCode">目的地省份ID</param>
        /// <param name="endCityCode">目的地城市ID</param>
        /// <param name="endCountyCode">目的地区县Id</param>
        /// <param name="goodsWeightLeft">货物重量左区间值</param>
        /// <param name="goodsWeightRight">货物重量右区间值</param>
        /// <param name="vehicleTypeId">车型ID</param>
        /// <param name="transportBusinessType">运输业务类型(订单类型)</param>
        /// <param name="vehicleCategoryName">车辆分类名称</param>
        /// <param name="phone">手机号</param>
        /// <param name="start">开始时间</param>
        /// <param name="end">结束时间</param>
        /// <param name="ascending"></param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        PageableList<OrderDto> Query(AdminDto adminDto, string orderNo, string vehicleNo, string provinceCode, string cityCode, string countyCode, OrderStatus? orderStatus,
             string goodsName, long? userId, long? driverId, string endProvinceCode, string endCityCode, string endCountyCode, decimal? goodsWeightLeft, decimal? goodsWeightRight,
             int? vehicleTypeId, TransportBusinessType? transportBusinessType, string vehicleCategoryName, string phone, DateTime? start, DateTime? end, bool? ascending, int pageIndex = 1,
             int pageSize = 20);

        #region 取消订单
        /// <summary>
        /// 取消订单
        /// </summary>
        /// <param name="userDto">用户信息</param>
        /// <param name="vehicleNo">车辆No</param>
        /// <param name="appType">App类型</param>
        /// <param name="orderCancelRequestDto">取消订单请求</param>
        /// <returns></returns>
        void CancelOrder(UserDto userDto, string vehicleNo, SourceAppType appType, OrderCancelRequestDto orderCancelRequestDto);
        #endregion

        #region 用户端App独立使用
        /// <summary>
        /// 用户端App独立使用查询订单列表
        /// </summary>
        /// <param name="userAppOrderStatus">用户端App订单状态</param>
        /// <param name="userId">用户Id</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        PageableList<OrderDto> ClientAppQueryOrders(UserAppOrderStatus userAppOrderStatus, long? userId, int pageIndex, int pageSize);
        #endregion

        #region 司机端App独立使用
        /// <summary>
        /// 司机端App独立使用查询订单列表
        /// </summary>
        /// <param name="driverAppOrderStatus">司机端App订单状态</param>
        /// <param name="vehicleId">车辆Id</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        PageableList<OrderDto> DriverAppQueryOrders(DriverAppOrderStatus driverAppOrderStatus, long? vehicleId, int pageIndex, int pageSize);

        /// <summary>
        /// 司机端App查询待抢单
        /// </summary>
        /// <param name="currentDriver">当前登录司机</param>
        /// <param name="transportBusinessType">运输业务</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        PageableList<OrderDto> DriverAppQueryPendingOrders(DriverDto currentDriver, TransportBusinessType? transportBusinessType, int pageIndex, int pageSize);
        /// <summary>
        /// 订单临时指派
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <param name="driverId">司机Id</param>
        /// <param name="distance">距离</param>
        /// <param name="admin">指派人</param>
        /// <returns></returns>
        bool AssignDriver(long orderId, long driverId, int? distance, AdminDto admin);

        /// <summary>
        /// 修改订单装卸货地址状态--已到达
        /// </summary>
        /// <param name="driverDto">司机信息</param>
        /// <param name="orderId">订单Id</param>
        /// <param name="coordinateDto">坐标</param>
        /// <param name="adminOperation">管理员操作</param>
        /// <returns></returns>
        bool UpdateOrderExtentionAddressStatus(DriverDto driverDto, long orderId, CoordinateBsonDto coordinateDto, bool? adminOperation);

        #region 司机装货
        /// <summary>
        /// 司机装货
        /// </summary>
        /// <param name="driverDto">司机信息</param>
        /// <param name="orderLoadingRequestDto">订单装货请求</param>
        /// <returns></returns>
        OrderDto OrderLoading(DriverDto driverDto, OrderLoadingRequestDto orderLoadingRequestDto);
        #endregion

        #region 司机出发
        /// <summary>
        /// 司机出发
        /// </summary>
        /// <param name="driverDto">司机信息</param>
        /// <param name="orderStartOutRequestDto">司机出发请求</param>
        /// <returns></returns>
        OrderDto StartOut(DriverDto driverDto, OrderStartOutRequestDto orderStartOutRequestDto);
        #endregion

        #region 创建订单支付二维码
        /// <summary>
        /// 创建订单支付二维码
        /// </summary>
        /// <param name="appType">App类型</param> 
        /// <param name="user">当前用户</param>
        /// <param name="vehicleDto">车辆信息</param>
        /// <param name="paymentRequestDto">支付请求信息</param>
        /// <param name="channelFactoryService">支付渠道服务</param>
        /// <returns></returns>
        PaymentQRCodeDto CreatePaymentQRCode(SourceAppType appType, UserDto user, DriverDto vehicleDto, PaymentRequestDto paymentRequestDto, IChannelFactoryService channelFactoryService);
        #endregion

        #region 司机签收签字
        /// <summary>
        /// 签收签字
        /// </summary>
        /// <param name="driver">司机信息</param>
        /// <param name="orderAcceptanceSignatureRequestDto">签收签字</param>
        /// <returns></returns>
        OrderDto AcceptanceSignature(DriverDto driver, OrderAcceptanceSignatureRequestDto orderAcceptanceSignatureRequestDto);
        #endregion

        #region 上传签收回单
        /// <summary>
        /// 上传签收回单
        /// </summary>
        /// <param name="driver">司机信息</param>
        /// <param name="orderReceiptPhotoRequestDto">订单回单请求</param>
        /// <returns></returns>
        OrderDto AcceptanceReceiptPhoto(DriverDto driver, OrderReceiptPhotoRequestDto orderReceiptPhotoRequestDto);
        #endregion

        #region 上传原始回单
        /// <summary>
        /// 上传原始回单
        /// </summary>
        /// <param name="driver">司机信息</param>
        /// <param name="orderReceiptPhotoRequestDto">订单回单请求</param>
        /// <returns></returns>
        OrderDto SourceReceiptPhoto(DriverDto driver, OrderReceiptPhotoRequestDto orderReceiptPhotoRequestDto);
        #endregion

        #region 验签完成后处理订单信息
        /// <summary>
        /// 司机端验签完成后处理订单信息
        /// </summary>
        /// <param name="payer">付款方</param>
        /// <param name="orderNo">订单编号</param>
        /// <param name="paymentRecordId">支付记录Id</param>
        /// <param name="payChannelType">支付渠道类型</param>
        /// <param name="amount">支付金额</param>
        /// <returns></returns>

        OrderDto CheckSignCompleteToProcessOrderInformation(OrderPayer payer, string orderNo, long paymentRecordId, PaymentChannelType payChannelType, decimal amount);

        #endregion

        #region 修改代收货款状态及时间
        /// <summary>
        /// 修改代收货款状态及时间
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <param name="paymentRecordId">支付记录Id</param>
        /// <returns></returns>
        OrderDto UpdateCodStatusAndTime(long orderId, long paymentRecordId);
        /// <summary>
        /// 修改代收货款状态及时间
        /// </summary>
        /// <param name="orderNo">订单编号</param>
        /// <param name="paymentRecordId">支付记录Id</param>
        /// <returns></returns>
        OrderDto UpdateCodStatusAndTime(string orderNo, long paymentRecordId);
        #endregion

        #region 订单签收
        OrderDto OrderSign(DriverDto driver, OrderSignPersonRequestDto orderSignPersonRequestDto);
        #endregion

        #endregion

        #region 检查订单费用是否已支付
        /// <summary>
        /// 检查订单费用是否已支付
        /// </summary>
        /// <param name="orderNo">订单编号</param>
        /// <returns></returns>
        bool CheckOrderPaid(string orderNo);
        #endregion

        #region 验签完成后处理订单信息
        /// <summary>
        /// 验签完成后处理订单信息
        /// </summary>
        /// <param name="payer">付款方</param>
        /// <param name="orderNo">订单编号</param>
        /// <param name="paymentRecordId">支付记录Id</param>
        /// <param name="payChannelType">支付渠道类型</param>
        /// <param name="amount">支付金额</param>
        /// <returns></returns>
        OrderDto CheckSignCompleteToProcessOrderInformation(SourcePayerType payer, string orderNo, long paymentRecordId, PaymentChannelType payChannelType, decimal amount);

        #endregion
    }
}
